package com.usian.wemedia.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.usian.common.wemedia.WemediaContans;
import com.usian.model.admin.dtos.NewsAuthDto;
import com.usian.model.base.BaseServiceImpl;
import com.usian.model.common.dtos.PageResponseResult;
import com.usian.model.common.dtos.ResponseResult;
import com.usian.model.common.enums.AppHttpCodeEnum;
import com.usian.model.media.dtos.WmNewsDto;
import com.usian.model.media.dtos.WmNewsPageReqDto;
import com.usian.model.media.dtos.WmNewsVo;
import com.usian.model.media.pojos.WmMaterial;
import com.usian.model.media.pojos.WmNews;
import com.usian.model.media.pojos.WmNewsMaterial;
import com.usian.model.media.pojos.WmUser;
import com.usian.utils.threadlocal.ThreadLocalUtils;
import com.usian.wemedia.mapper.WmMaterialMapper;
import com.usian.wemedia.mapper.WmNewsMapper;
import com.usian.wemedia.mapper.WmNewsMaterialMapper;
import com.usian.wemedia.mapper.WmUserMapper;
import com.usian.wemedia.service.WmNewsService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class WmNewsServiceImpl extends BaseServiceImpl<WmNewsMapper, WmNews> implements WmNewsService {
    @Value("${fdfs.url}")
    private String baseUrl;

    @Autowired
    private WmMaterialMapper wmMaterialMapper;

    @Autowired
    private WmNewsMaterialMapper wmNewsMaterialMapper;

    @Autowired
    private KafkaTemplate  kafkaTemplate;

    @Autowired
    private WmNewsMapper wmNewsMapper;

    @Autowired
    private WmUserMapper wmUserMapper;

    @Override
    public ResponseResult findAll(WmNewsPageReqDto dto) {
        if(dto == null) return errorParam;
        LambdaQueryWrapper<WmNews> wrapper =  new LambdaQueryWrapper<>();
        //状态的判断，可以传过去，也可以不传
        if(dto.getStatus() != null)wrapper.eq(WmNews::getStatus,dto.getStatus());
        //频道的判断，可以传过去，也可以不传
        if(dto.getChannelId()!=null)wrapper.eq(WmNews::getChannelId,dto.getChannelId());
        //对标题的模糊查询,可以传过去，也可以不传
        if(dto.getKeyword() !=null)wrapper.like(WmNews::getTitle,dto.getKeyword());
        //如果第一页的展示没有时间
        if(dto.getMaxTime() ==null)dto.setMaxTime(new Date());
        //排序方式
        wrapper.lt(WmNews::getPublishTime,dto.getMaxTime());
        wrapper.orderByDesc(WmNews::getPublishTime);
        //只能查询自己的数据通过登录的id
         wrapper.eq(WmNews::getUserId, ThreadLocalUtils.getUserId());
        return getPageData(dto,wrapper);
    }

    @Override
    public ResponseResult saveNews(WmNewsDto wmNews) {
        if(wmNews == null) return errorParam;
        if(wmNews.getType() == -1) wmNews.setType(null);
        WmNews news = new WmNews();
        //把wmNews的值复制到新对象中
        BeanUtils.copyProperties(wmNews,news);
        news.setUserId(ThreadLocalUtils.getUserId());
        news.setSubmitedTime(new Date());
        news.setCreatedTime(new Date());

        Boolean goAuto = false;

        //判断传过来的id为空则是保存数据，反之修改数据
        if(wmNews.getId() == null){
           //新增的新闻数据
            goAuto = save(news);
        }else {
            goAuto = updateById(news);
           wmNewsMaterialMapper.delete(Wrappers.<WmNewsMaterial>lambdaQuery().eq(WmNewsMaterial::getNewsId,wmNews.getId()));
        }
        saveRelations(news,wmNews);
        if(goAuto){
            kafkaTemplate.send(WemediaContans.Auto_Scan,news.getId()+"");
        }
        return success;
    }

    @Override
    public ResponseResult findWmnewsById(Integer id) {
        if(id == null) return errorParam;
        WmNews wmNews = getById(id);
        if(wmNews ==null) return noData;
        return ResponseResult.okResult(wmNews);
    }

    @Override
    public ResponseResult delNews(Integer id) {
        if(id == null) return errorParam;
        WmNews news = getById(id);
        if(news == null) return noData;
        if(news.getStatus().equals(WmNews.Status.PUBLISHED.getCode()) || news.getEnable() == 1){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,"已发布的或上架的新闻不能删除");
        }
        removeById(id);
        wmNewsMaterialMapper.delete(Wrappers.<WmNewsMaterial>lambdaQuery().eq(WmNewsMaterial::getNewsId,id));
        return success;
    }

    @Override
    public ResponseResult downOrUp(WmNewsDto dto) {
        if(dto == null) return errorParam;
        if(dto.getEnable()==null || (dto.getEnable()!=0 && dto.getEnable()!=1)) return errorParam;
        WmNews news = getById(dto.getId());
        if (news == null) return noData;
        if(!news.getStatus().equals(WmNews.Status.PUBLISHED))return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST,
                "当前文章不是发布状态，不能上下架");
        update(Wrappers.<WmNews>lambdaUpdate().eq(WmNews::getId,dto.getId()).set(WmNews::getEnable,dto.getEnable()));
        return success;
    }

    @Override
    public List<Integer> findRelease() {
        List<WmNews> list = list(Wrappers.<WmNews>lambdaQuery().eq(WmNews::getStatus, 8).lt(WmNews::getPublishTime,new Date()));
        List<Integer> resultList = list.stream().map(WmNews::getId).collect(Collectors.toList());
        return resultList;
    }

    //把三查出来改成四
    @Override
    public PageResponseResult findList(NewsAuthDto dto) {
        //1.检查参数
        dto.checkParam();
        //设置起始页
        dto.setPage((dto.getPage()-1)*dto.getSize());
        dto.setTitle("%"+dto.getTitle()+"%");

        //2.分页查询
        List<WmNewsVo> list = wmNewsMapper.findListAndPage(dto);
        //统计多少条数据
        int count = wmNewsMapper.findListCount(dto);

        //3.结果返回
        PageResponseResult responseResult = new PageResponseResult(dto.getPage(),dto.getSize(),count);
        responseResult.setData(list);
        return responseResult;
    }

    @Override
    public WmNewsVo findWmNewsVo(Integer id) {
        //1.查询文章信息
        WmNews wmNews = getById(id);
        //2.查询作者
        WmUser wmUser = null;
        if(wmNews!=null && wmNews.getUserId() != null){
            wmUser = wmUserMapper.selectById(wmNews.getUserId());
        }

        //3.封装vo信息返回
        WmNewsVo wmNewsVo = new WmNewsVo();
        BeanUtils.copyProperties(wmNews,wmNewsVo);
        if(wmUser != null){
            wmNewsVo.setAuthorName(wmUser.getName());
        }
        return wmNewsVo;
    }

    //批量插入抽取方法
    private  void moreinsert(Integer newsId,List<String> urls,Short referenceType){
        //通过 登录id、素材集合 来进行查询数据
        LambdaQueryWrapper<WmMaterial>  materialLWrapper  = new LambdaQueryWrapper<>();
        materialLWrapper.eq(WmMaterial::getUserId,ThreadLocalUtils.getUserId());
            materialLWrapper.in(WmMaterial::getUrl,urls);
        List<WmMaterial> list =  wmMaterialMapper.selectList(materialLWrapper);
        //之后赋值到另一个集合中
        List<String> ids = list.stream().map(m -> m.getId() + "").collect(Collectors.toList());
        //中间表的批量添加
        wmNewsMaterialMapper.saveRelationsByContent(ids,newsId,referenceType);
    }

    private void saveRelations(WmNews saveNews,WmNewsDto wmNews){
        //返回一个id
        Integer newsId = saveNews.getId();
        String content = saveNews.getContent();
        JSONArray array = JSON.parseArray(content);
        //定义一个集合存储传过来的素材
        List<String> materialUrlList_content = new ArrayList<>();
        array.forEach(o->{
            JSONObject object = JSON.parseObject(o.toString());
            if(object.getString("type").equals("image")){
                String value = object.getString("value");
                materialUrlList_content.add(value.replace(baseUrl,""));
            }
        });
        //对素材表查询数据之后，然后中间表的保存
        moreinsert(newsId,materialUrlList_content,WemediaContans.WM_CONTENT_REFERENCE);
        //上边已经将保存的情况下内容中图片和新闻的关系进行了处理，下边主要是处理保存的时候封面图和新闻id的关系
        WmNews updateNews = new WmNews();
        if(wmNews.getType() != null){ //前端没选自动
            List<String> images = wmNews.getImages();
            if(images !=null && images.size() !=0){
                images = images.stream().map(m->m.replace(baseUrl,"")).collect(Collectors.toList());
                moreinsert(newsId,images,WemediaContans.WM_COVER_REFERENCE);
            }
            StringBuilder builder = new StringBuilder();
            for (String url : images) {
                builder.append(url).append(",");
            }
            String imageStr = builder.toString().substring(0,builder.toString().length()-1);
            updateNews.setImages(imageStr);
            updateNews.setId(saveNews.getId());
            updateById(updateNews);
        }else {  //自动、要根据内容里的图片数量来决定到底是几图模式
            updateNews.setId(newsId);
            if(materialUrlList_content.size()!=0){
                List<String> autoCoverUrls = materialUrlList_content.size() <3 ? Arrays.asList(materialUrlList_content.get(0)) :
                        Arrays.asList(materialUrlList_content.get(0),materialUrlList_content.get(1),materialUrlList_content.get(2));
                moreinsert(newsId,autoCoverUrls,WemediaContans.WM_COVER_REFERENCE);
                StringBuilder builder = new StringBuilder();
                for (String url : autoCoverUrls) {
                    builder.append(url).append(",");
                }
                String images = builder.toString().substring(0,builder.toString().length()-1);

                updateNews.setImages(images);
                updateNews.setType(autoCoverUrls.size()<3
                        ?WemediaContans.WM_NEWS_SINGLE_IMAGE:WemediaContans.WM_NEWS_MANY_IMAGE);
            }else {
                updateNews.setImages("");
                updateNews.setType(WemediaContans.WM_NEWS_NONE_IMAGE);
            }
            updateById(updateNews);
        }
    }

}
